import type { Tile } from "./tile";

export class HTMLActuator {
  tileContainer: any;
  overContainer: any;
  boxContainer: any;
  boxClientRect: any;

  constructor(tileContainer: any, overContainer: any, boxContainer: any) {
    this.tileContainer = tileContainer;
    this.overContainer = overContainer;
    this.boxContainer = boxContainer;
    this.boxClientRect = this.boxContainer?.getBoundingClientRect();
  }
  // 更新页面网格样式和内容
  actuate(data: { grid: { cells: any[]; }; score: number, over: boolean; boxHeight: number; }) {
    const self = this;
    console.log('actuate', data);
    return new Promise((resolve) => {
      window.requestAnimationFrame(() => {
        self.clearContainer(self.tileContainer);
        data.grid.cells.forEach(column => {
          column.forEach((cell: any) => {
            if (cell) {
              self.addTile(cell);
            }
          });
        });
        if (data.over) {
          self.updateOver();
        }
        self.upTileContainer(data.boxHeight)
        resolve(true);
      });
    })
  }

  clearContainer(container: { firstChild: any; removeChild: (arg0: any) => void; }) {
    while (container.firstChild) {
      container.removeChild(container.firstChild);
    }
  }
  addTile(tile: Tile) {
    const pao = document.createElement("div");
    const positionClass = this.positionClass({ x: tile.x, y: tile.y });
    const classes = ["pao", "pao-" + tile.color, positionClass];
    this.applyClasses(pao, classes);
    this.tileContainer.appendChild(pao);
    pao.textContent = tile.x + "-" + tile.y;
    // const info = pao.getBoundingClientRect()
    // tile.updateStylePosition({ l: info.left - this.boxClientRect.left, t: info.top - this.boxClientRect.top });
    tile.updateDom(pao);
    // console.log('addTile', tile, info);
  }

  removeTile(tile: Tile) {
    return new Promise((resolve) => {
      if (!tile.dom || !tile.dom.parentNode) {
        resolve(1);
        return;
      }
      if (tile.dom) {
        tile.dom.classList.add('pao-removed');
        setTimeout(() => {
          try {
            if (tile.dom && tile.dom.parentNode) {
              tile.dom.parentNode.removeChild(tile.dom);
            }
          } catch (e) {
            // 忽略 DOM 已经不存在的情况
          }
          resolve(1)
        }, 300); // 动画时长
      }
    })
  }
  dropTile(tile: Tile, delay: number = 0) {
    return new Promise((resolve) => {
      if (!tile.dom || !tile.dom.parentNode) {
        resolve(1);
        return;
      }
      setTimeout(() => {
        if (tile.dom) {
          tile.dom.classList.add('pao-droped');
          setTimeout(() => {
            try {
              if (tile.dom && tile.dom.parentNode) {
                tile.dom.parentNode.removeChild(tile.dom);
              }
            } catch (error) {

            }
            resolve(1)
          }, 500); // 动画时长
        }
      }, delay); // 随机延迟
    })
  }

  updateTileStylePosition(tile: Tile) {
    tile.dom?.setAttribute("style", `left:${tile.l}px;top:${tile.t}px;`)
  }

  applyClasses(element: HTMLDivElement, classes: any[]) {
    element.setAttribute("class", classes.join(" "));
  }

  normalizePosition(position: { x: number; y: number; }) {
    return { x: position.x, y: position.y };
  }

  positionClass(position: { x: any; y: any; }) {
    position = this.normalizePosition(position);
    if (position.x % 2 == 0) {
      return "pao-position-" + position.x + "-" + position.y + '-even';
    } else {
      return "pao-position-" + position.x + "-" + position.y;
    }
  }

  updateOver() {
    // this.clearContainer(this.overContainer);
    this.overContainer.style.zIndex = 9;
    this.overContainer.textContent = '游戏结束';
    // if (difference > 0) {
    //   const addition = document.createElement("div");
    //   addition.classList.add("score-addition");
    //   addition.textContent = "+" + difference;

    //   this.overContainer.appendChild(addition);
    // }
  }
  drawLine(ways: { l: number, t: number, dis?: number, hl?: number, ht?: number }[]) {
    // console.log('绘制路线===============================================', ways);
    const r = 15 // 泡泡半径
    const size = 2 * r // 泡泡直径
    const yd = Math.sqrt(3) * r; // (Math.sqrt(3) / 2) * (2 * this.paoRadius)
    this.clearLine();// 清除之前的辅助线

    for (let i = 0; i < ways.length - 1; i++) {
      // const p1 = ways[i];    // 线段起点
      // const p2 = ways[i + 1];  // 线段终点
      // // 计算两个小球的中心点
      // const startGrid = { x: Math.floor(p1.t / yd), y: Math.floor(p1.l / size) };
      // const endGrid = { x: Math.floor(p2.t / yd), y: Math.floor(p2.l / size) };

      // this.drawTestPoint({ cl: startGrid.x % 2 == 0 ? size * startGrid.y : size * startGrid.y + r, ct: yd * startGrid.x }) // 绘制起点
      // this.drawTestPoint({ cl: endGrid.x % 2 == 0 ? size * endGrid.y : size * endGrid.y + r, ct: yd * endGrid.x }) // 绘制终点

      // const start = { l: startGrid.x % 2 == 0 ? size * startGrid.y : size * startGrid.y + r, t: yd * startGrid.x }
      // const end = { l: endGrid.x % 2 == 0 ? size * endGrid.y : size * endGrid.y + r, t: yd * endGrid.x }

      const start = ways[i];    // 线段起点
      const end = ways[i + 1];  // 线段终点

      // 计算线段几何特性
      const dx = end.l - start.l; // 水平距离
      const dy = end.t - start.t; // 垂直距离
      const angle = Math.atan2(dy, dx) * 180 / Math.PI; // 角度（弧度转角度）
      const length = Math.sqrt(dx * dx + dy * dy); // 线段长度

      const line = document.createElement("div")
      line.className = "bubble-line"; // 添加类名便于后续管理

      // 设置线段样式
      Object.assign(line.style, {
        position: "absolute",
        left: `${start.l + r}px`,
        top: `${start.t + r}px`,
        width: `${length}px`,
        height: "3px",
        backgroundColor: "rgba(0, 0, 0, 0.5)", // 不同线段不同颜色
        transformOrigin: "0 0",
        transform: `rotate(${angle}deg)`,
        zIndex: "100",
        transition: "opacity 0.3s"
      });

      // console.log('line', start, end, startGrid, endGrid);

      this.boxContainer.appendChild(line);
    }
  }
  clearLine() {
    const existingLines = this.boxContainer.querySelectorAll('.bubble-line');
    existingLines.forEach((line: { remove: () => any; }) => line.remove());
  }
  drawTestPoint(point: { cl: number, ct: number }, color: string = "rgba(255, 253, 132, 0.3)") {
    const container: any = document.getElementById('game-box');
    const newElement = document.createElement('div');
    newElement.style.position = 'absolute';
    newElement.style.left = `${point.cl}px`;
    newElement.style.top = `${point.ct}px`;
    newElement.style.width = 30 + 'px';
    newElement.style.height = 30 + 'px';
    newElement.style.backgroundColor = color;
    newElement.style.borderRadius = '50%';
    newElement.style.zIndex = '3';
    container.appendChild(newElement);
    return newElement
  }
  upTileContainer(boxHeight: number) {
    let self = this;
    return new Promise((resolve) => {
      setTimeout(() => {
        self.tileContainer.style.height = boxHeight + 'px'
        self.tileContainer.style.transition = 'transform 0.3s ease-out';
        resolve(1)
      }, 0)
    })
  }
}

